import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_hsh/utils/toast_utils.dart';
import 'package:get/get.dart';
import '../../fluttergromore/utils/sp_utils.dart';
import '../Home/health_score_logic.dart';

/// 垃圾文件项数据模型
class JunkItem {
  final String name;
  final String path;
  final String category;
  final String size;
  final int sizeInBytes;

  JunkItem({
    required this.name,
    required this.path,
    required this.category,
    required this.size,
    required this.sizeInBytes,
  });
}

class JunkCleanupLogic extends GetxController {
  // 状态变量
  final RxBool isScanning = false.obs;
  final RxString scanStatus = '正在扫描...'.obs;
  final RxDouble scanProgress = 0.0.obs;
  final RxList<JunkItem> scanResults = <JunkItem>[].obs;
  final RxList<bool> selectedItems = <bool>[].obs;
  final RxBool isAllSelected = false.obs;
  final RxBool isCleaning = false.obs;
  // 清理完成展示页状态开关
  final RxBool showSuccess = false.obs;
  // 本次清理释放空间大小（文本），用于成功页展示
  final RxString lastFreedSize = '0B'.obs;
  // 清理进度（0-1），驱动清理中动画
  final RxDouble cleaningProgress = 0.0.obs;

  @override
  void onInit() {
    super.onInit();
    // 初始化时清空数据
    scanResults.clear();
    selectedItems.clear();
  }

  /// 开始扫描垃圾文件
  Future<void> startScan() async {
    try {
      // 关键逻辑：若一小时内刚清理过，则直接提示“手机已经很干净”，并跳过扫描
      final bool recentlyCleaned = await _isRecentlyCleanedWithinOneHour();
      if (recentlyCleaned) {
        scanResults.clear();
        selectedItems.clear();
        isScanning.value = false;
        scanStatus.value = '最近已清理，手机已经很干净';
        MyToast.show('手机已经很干净了，暂时没有垃圾');
        return; // 提前返回，避免继续扫描
      }

      isScanning.value = true;
      scanStatus.value = '正在扫描系统文件...';
      scanProgress.value = 0.0;
      scanResults.clear();
      selectedItems.clear();
      isAllSelected.value = false;

      // 模拟扫描过程
      await _simulateScan();

      MyToast.show('扫描完成，发现 ${scanResults.length} 个垃圾文件');
    } catch (e) {
      MyToast.show('扫描失败：${e.toString()}');
    } finally {
      isScanning.value = false;
    }
  }

  /// 模拟扫描过程
  Future<void> _simulateScan() async {
    final scanSteps = [
      '正在扫描缓存文件...',
      '正在扫描临时文件...',
      '正在扫描日志文件...',
      '正在扫描广告缓存...',
      '正在扫描卸载残留...',
      '扫描完成',
    ];

    for (int i = 0; i < scanSteps.length; i++) {
      scanStatus.value = scanSteps[i];
      scanProgress.value = (i + 1) / scanSteps.length;
      
      // 在扫描过程中添加一些模拟数据
      if (i < scanSteps.length - 1) {
        _addSimulatedJunkItems(i);
      }
      
      await Future.delayed(const Duration(milliseconds: 800));
    }
  }

  /// 添加模拟的垃圾文件数据
  void _addSimulatedJunkItems(int step) {
    final random = math.Random();
    final categories = ['缓存文件', '临时文件', '日志文件', '广告缓存', '卸载残留'];
    final fileNames = [
      ['浏览器缓存', '图片缓存', '视频缓存'],
      ['系统临时文件', '应用临时文件', '下载临时文件'],
      ['系统日志', '应用日志', '错误日志'],
      ['广告缓存', '推广缓存', '推荐缓存'],
      ['残留配置文件', '残留数据文件', '残留缓存文件'],
    ];

    // 每个步骤添加2-4个文件
    final fileCount = random.nextInt(3) + 2;
    
    for (int j = 0; j < fileCount; j++) {
      final category = categories[step];
      final categoryFiles = fileNames[step];
      final fileName = categoryFiles[random.nextInt(categoryFiles.length)];
      
      // 随机大小 (100KB - 50MB)
      final sizeInKB = random.nextInt(50000) + 100;
      final sizeText = _formatFileSize(sizeInKB * 1024);
      
      final junkItem = JunkItem(
        name: '$fileName ${random.nextInt(100)}',
        path: '/data/cache/$fileName${random.nextInt(1000)}.tmp',
        category: category,
        size: sizeText,
        sizeInBytes: sizeInKB * 1024,
      );
      
      scanResults.add(junkItem);
      selectedItems.add(true); // 默认选中
    }
  }

  /// 格式化文件大小
  String _formatFileSize(int bytes) {
    if (bytes < 1024) return '${bytes}B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)}KB';
    if (bytes < 1024 * 1024 * 1024) return '${(bytes / (1024 * 1024)).toStringAsFixed(1)}MB';
    return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)}GB';
  }

  /// 切换单个项目选中状态
  void toggleItemSelection(int index, bool selected) {
    if (index < selectedItems.length) {
      selectedItems[index] = selected;
      _updateAllSelectedStatus();
    }
  }

  /// 切换全选状态
  void toggleAllSelection(bool selectAll) {
    isAllSelected.value = selectAll;
    for (int i = 0; i < selectedItems.length; i++) {
      selectedItems[i] = selectAll;
    }
  }

  /// 更新全选状态
  void _updateAllSelectedStatus() {
    if (selectedItems.isEmpty) {
      isAllSelected.value = false;
      return;
    }
    
    isAllSelected.value = selectedItems.every((selected) => selected);
  }

  /// 获取选中的项目数量
  int getSelectedCount() {
    return selectedItems.where((selected) => selected).length;
  }

  /// 获取选中的项目总大小
  String getSelectedSize() {
    int totalSize = 0;
    for (int i = 0; i < selectedItems.length; i++) {
      if (selectedItems[i]) {
        totalSize += scanResults[i].sizeInBytes;
      }
    }
    return _formatFileSize(totalSize);
  }

  /// 获取选中项目的总字节数（用于准确计算释放空间）
  int getSelectedBytes() {
    int total = 0;
    for (int i = 0; i < selectedItems.length; i++) {
      if (selectedItems[i]) {
        total += scanResults[i].sizeInBytes;
      }
    }
    return total;
  }

  /// 开始清理选中的垃圾文件
  Future<void> startCleanup() async {
    final selectedCount = getSelectedCount();
    if (selectedCount == 0) {
      MyToast.show('请选择要清理的文件');
      return;
    }

    try {
      // 记录释放空间与初始化动画状态
      final freedBytes = getSelectedBytes();
      lastFreedSize.value = _formatFileSize(freedBytes);
      cleaningProgress.value = 0.0;
      showSuccess.value = false;
      isCleaning.value = true; // 切换到清理中页面
      MyToast.show('开始清理垃圾文件...');

      // 模拟清理过程
      await _simulateCleanup();

      // 清理完成后展示成功页
      isCleaning.value = false;
      showSuccess.value = true;
      MyToast.show('清理完成，释放了 ${lastFreedSize.value} 空间');

      // 写入最近清理时间（毫秒时间戳），用于一小时内提示“已很干净”
      await SpUtils.instance.put('junk_last_cleanup_ts', DateTime.now().millisecondsSinceEpoch);

      // 联动健康分：根据释放的空间更新存储得分与综合分
      try {
        final healthScoreLogic = Get.find<HealthScoreLogic>();
        // 根据选中项总字节数更新评分
        healthScoreLogic.applyStorageFreed(freedBytes);
        // 清理完成后：隐藏首页“垃圾清理”红点
        healthScoreLogic.showJunkDot.value = false;
      } catch (_) {
        // 若未找到健康评分控制器，忽略（例如从其它入口打开页面）
      }

      // 2秒后自动返回并重新扫描
      Future.delayed(const Duration(seconds: 2), () async {
        // showSuccess.value = false;
        // await startScan();
        Get.back();
      });
    } catch (e) {
      MyToast.show('清理失败：${e.toString()}');
    } finally {
      // isCleaning/showSuccess 的切换由流程控制，不在 finally 中强制关闭
    }
  }

  /// 模拟清理过程
  Future<void> _simulateCleanup() async {
    final selectedCount = getSelectedCount();
    
    // 分批清理，每批清理2-3个文件
    const batchSize = 3;
    int cleanedCount = 0;
    
    while (cleanedCount < selectedCount) {
      final currentBatchSize = math.min(batchSize, selectedCount - cleanedCount);
      
      // 找到当前批次要清理的项目
      final itemsToRemove = <int>[];
      int batchCount = 0;
      
      for (int i = 0; i < selectedItems.length && batchCount < currentBatchSize; i++) {
        if (selectedItems[i]) {
          itemsToRemove.add(i);
          batchCount++;
        }
      }
      
      // 等待一段时间模拟清理过程
      await Future.delayed(const Duration(milliseconds: 500));
      
      // 从后往前删除，避免索引问题
      for (int i = itemsToRemove.length - 1; i >= 0; i--) {
        final index = itemsToRemove[i];
        scanResults.removeAt(index);
        selectedItems.removeAt(index);
      }
      
      cleanedCount += currentBatchSize;
      
      // 更新选中状态
      _updateAllSelectedStatus();
      // 更新清理进度（驱动动画）
      cleaningProgress.value = cleanedCount / selectedCount;
      
      // 显示进度
      if (cleanedCount < selectedCount) {
        MyToast.show('已清理 $cleanedCount/$selectedCount 个项目');
      }
    }
    // 确保进度到100%
    cleaningProgress.value = 1.0;
  }

  /// 判断是否在一小时内刚清理过（用于直接提示“手机已经很干净了”）
  Future<bool> _isRecentlyCleanedWithinOneHour() async {
    // 说明：使用 SpUtils 读取时间戳，遵循项目统一存储规范，避免直接实例化 SharedPreferences
    final lastTs = await SpUtils.instance.get('junk_last_cleanup_ts', 0);
    if (lastTs is int && lastTs > 0) {
      final now = DateTime.now().millisecondsSinceEpoch;
      const oneHourMs = 60 * 60 * 1000;
      return (now - lastTs) < oneHourMs;
    }
    return false;
  }
}